iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
JavaScript

不要再說你不會後端!30 天 Node.js 降維打擊指南 系列 第 12 篇

Day 12:請求資料的守門員--Express 中得 Request Data與驗證機制

  • 分享至 

  • xImage
  •  

前情提要: 在 Day 11 我們學習了 Express 的靈魂核心——中間件(Middleware)。今天我們要運用中間件的觀念,為 API 建立嚴密的「資料守門員」,解析與驗證前端傳入的各式請求資料(Request Data)。

  1. Express 接收前端資料的三大途徑
    在 Express 中,前端傳遞資料到後端主要有以下三種途徑:

傳送方式 Express 讀取方式 適用情境 範例 URL / 語法
Path Parameters req.params 指定特定資源識別碼 (ID) /api/users/:id
Query Parameters req.query 篩選、排序、分頁等可選條件 /api/users?page=1&limit=10
Request Body req.body 新增/修改的大筆 JSON 資料 POST / PUT 的 Payload
實戰範例:讀取各種請求資料
JavaScript
const express = require('express');
const app = express();

// 解析 JSON Body 的關鍵中間件,未掛載時 req.body 會是 undefined
app.use(express.json());

// 1. Path Params + Query Params
// GET /api/products/electronics?sort=price_asc
app.get('/api/products/:category', (req, res) => {
const { category } = req.params; // electronics
const { sort } = req.query; // price_asc

res.json({ category, sort });
});

// 2. Request Body
// POST /api/users
app.post('/api/users', (req, res) => {
const { username, email, age } = req.body;

res.status(201).json({
message: '成功接收資料',
data: { username, email, age }
});
});
2. 為什麼後端必須做資料驗證 (Validation)?
後端開發黃金定律: 永遠不要相信前端傳過來的任何資料(Never trust user input)。

如果沒有進行嚴格的資料驗證,可能引發以下問題:

資料庫污染:寫入型態錯誤或格式不合規範的資料(例如:年齡欄位收到字串 "abc")。

伺服器崩潰:漏傳必填欄位導致程式讀取 undefined 屬性時拋出 TypeError 崩潰。

資安風險:缺乏過濾的輸入容易遭受注入攻擊(Injection Attacks)。

  1. 使用 Joi 建立驗證中間件
    Joi 是 Node.js 生態系中廣泛使用的資料 Schema 驗證套件。

安裝 Joi
Bash
npm install joi
撰寫驗證 Schema 與 Middleware
JavaScript
// middleware/validateUser.js
const Joi = require('joi');

// 1. 定義資料規格 (Schema)
const userSchema = Joi.object({
username: Joi.string().alphanumeric().min(3).max(30).required().messages({
'string.empty': '使用者名稱為必填欄位',
'string.min': '使用者名稱最少需要 3 個字元'
}),
email: Joi.string().email().required().messages({
'string.email': '請提供有效的 Email 格式'
}),
password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{6,30}$')).required().messages({
'string.pattern.base': '密碼需為 6-30 位英數字組合'
}),
age: Joi.number().integer().min(18).max(100)
});

// 2. 封裝為 Express Middleware
const validateUser = (req, res, next) => {
const { error, value } = userSchema.validate(req.body, { abortEarly: false });

if (error) {
const errorMessages = error.details.map(detail => detail.message);
return res.status(400).json({
error: 'Bad Request',
details: errorMessages
});
}

// 將驗證過後的安全資料覆蓋 req.body
req.body = value;
next();
};

module.exports = validateUser;
4. 整合驗證機制至路由
JavaScript
// app.js
const express = require('express');
const validateUser = require('./middleware/validateUser');

const app = express();
app.use(express.json());

// 將 validateUser 掛載在 POST 路由前
app.post('/api/register', validateUser, (req, res) => {
// 能執行到這裡,代表 req.body 已通過百分之百的資料驗證!
const { username, email } = req.body;

res.status(201).json({
message: '使用者註冊成功!',
user: { username, email }
});
});

app.listen(3000, () => console.log('Server is running on http://localhost:3000'));
5. 今日重點整理
[!IMPORTANT]

職責分離:資料驗證應單獨抽離為 Middleware,保持 Route Handler 專注處理商業邏輯。

明確回應:驗證失敗時統一回傳 400 Bad Request 與明確的錯誤細節,便於前端除錯。

別忘記解析 Body:接收 req.body 前務必載入 express.json()。


上一篇
Day 11: Express 的靈魂核心—— Middleware 流程與機制實戰
下一篇
Day13
系列文
不要再說你不會後端!30 天 Node.js 降維打擊指南 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言